package com.project.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.common.api.CommonFileApi;
import com.common.utils.StringUtils;
import com.project.domain.bo.DmBudgetStandardBo;
import com.project.domain.entity.*;
import com.project.domain.vo.DmBudgetStandardVo;
import com.project.mapper.BudgetStandardDateMapper;
import com.project.mapper.BudgetStandardMapper;
import com.project.mapper.UpLoadFileMapper;
import com.project.service.IBudgetStandardService;
import com.project.service.IBudgetSubjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 预算标准Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-08
 */
@Service
public class BudgetStandardServiceImpl implements IBudgetStandardService {
    @Autowired
    private BudgetStandardMapper baseMapper;

    @Autowired
    private IBudgetSubjectService subjectService;

    @Autowired
    private BudgetStandardDateMapper standardDateMapper;

    @Autowired
    private ProjectTypeServiceImpl projectTypeService;

    //只能CRUD记录本身
    @Autowired
    private UpLoadFileMapper fileMapper;

    //通用文件api  -能删文件和记录
    @Autowired
    private CommonFileApi fileApi;

    /**
     * 查询预算标准
     *
     * @param id 预算标准主键
     * @return 预算标准
     */
    @Override
    public DmBudgetStandardVo selectDmBudgetStandardByID(String id) {
        DmBudgetStandardVo dmBudgetStandardVo = baseMapper.selectStandardByID(id);
        String policyFileIds = dmBudgetStandardVo.getPolicyFileId();
        //文件
        List<Map<String, String>> fileList = new ArrayList<>();
        if (StringUtils.hasText(policyFileIds)) {
            String[] split = policyFileIds.split(",");
            for (String s : split) {
                SysUploadFile uploadFile = fileMapper.selectById(s);
                if (uploadFile != null) {
                    Map<String, String> map = new HashMap<>();
                    map.put("id", s);
                    map.put("name", uploadFile.getUploadfilename());
                    fileList.add(map);
                }
            }

            dmBudgetStandardVo.setPolicyFileList(fileList);
        }


        List<DmBudgetSubject> subjectList = dmBudgetStandardVo.getSubjectList();
        List<DmBudgetSubject> treeSubjectList = buildTree("", subjectList);
        dmBudgetStandardVo.setSubjectList(treeSubjectList);
        return dmBudgetStandardVo;
    }

    /**
     * 查询预算标准列表
     *
     * @param projectClass 区分横向和纵向/校级
     * @return 预算标准
     */
    @Override
    public List<DmBudgetStandardVo> selectDmBudgetStandardList(String projectClass) {
        List<DmBudgetStandardVo> dmBudgetStandardVos = baseMapper.selectStandardList(projectClass);

        //给每个预算标准下的预算科目组装成树形结构
        dmBudgetStandardVos.forEach(vo -> {
            List<DmBudgetSubject> subjectList = vo.getSubjectList();
//            List<DmBudgetSubject> treeSubjectList = buildTree(null, subjectList);
            List<DmBudgetSubject> treeSubjectList = buildTree("", subjectList);
            vo.setSubjectList(treeSubjectList);
        });
        return dmBudgetStandardVos;
    }


    /**
     * @param parentId 传入最上一层父节点id
     * @param treeList
     * @return
     */
    public List<DmBudgetSubject> buildTree(String parentId, List<DmBudgetSubject> treeList) {
        List<DmBudgetSubject> list = treeList.stream()
                // 筛选父节点
//                .filter(t -> (parentId == null && t.getUpCode() == null) || (parentId != null && parentId.equals(t.getUpCode())))
                .filter(t -> (parentId.equals(t.getUpCode())))
                // 递归设置子节点
                .map(item -> {
                    item.setChildren(buildTree(item.getCode(), treeList));
                    return item;
                })
                .collect(Collectors.toList());
        return list;
    }

    /**
     * 新增预算标准
     *
     * @param bo 预算标准
     * @return 结果 100 -> 科目编号已存在
     * 200  -> 新增加成功
     * 500  -> 新增失败
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertDmBudgetStandard(DmBudgetStandardBo bo) {
        DmBudgetStandard standard = bo.getStandard();
        //科目前缀
        String prefix = standard.getPrefix();
        LambdaQueryWrapper<DmBudgetStandard> lqw = new LambdaQueryWrapper<>();
        lqw.eq(DmBudgetStandard::getPrefix, prefix);
        //科目前缀的数量
        Long prefixNum = baseMapper.selectCount(lqw);
        if (prefixNum != 0L) return 100;

        List<DmBudgetSubject> subjectList = bo.getSubjectList();
        Boolean insertStandard = baseMapper.insert(standard) > 0;
        String standardId = standard.getId();

        //保存之下的预算科目
        List<DmBudgetSubject> childrenList = new ArrayList<>();
        if (insertStandard && !subjectList.isEmpty()) {
            subjectList.forEach(e -> {
                e.setStandardId(standardId);
                String code = e.getCode();
                // 递归处理每个分类科目的子科目
                addChildren(e, code, standardId, childrenList, 0);
            });
            subjectList.addAll(childrenList);
            boolean insertSubject = subjectService.saveBatch(subjectList);
            return insertSubject ? 200 : 500;
        }
        return insertStandard ? 200 : 500;
    }

    /**
     * 修改预算标准
     *
     * @param dmBudgetStandard 预算标准
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateDmBudgetStandard(DmBudgetStandardBo dmBudgetStandard) {
        DmBudgetStandard standard = dmBudgetStandard.getStandard();
        List<DmBudgetSubject> subjectList = dmBudgetStandard.getSubjectList();
        String standardId = standard.getId();
        //1.修改预算标准
        Boolean updateBase = baseMapper.updateById(standard) > 0;
        if (subjectList.isEmpty()) return updateBase;

        //2.查出对应的所有预算科目表
        LambdaQueryWrapper<DmBudgetSubject> subjectWrapper = new LambdaQueryWrapper<>();
        subjectWrapper.eq(DmBudgetSubject::getStandardId, standard.getId());
        //原来的预算科目
        List<DmBudgetSubject> list_old = subjectService.list(subjectWrapper);

        //2.删除预算科目表
        subjectService.removeByIds(list_old);

        //2.修改预算对应的预算科目
        List<DmBudgetSubject> childrenList = new ArrayList<>();
        subjectList.forEach(e -> {
            String code = e.getCode();
            //设置外键
            e.setStandardId(standardId);
            // 递归处理每个分类科目的子科目
            addChildren(e, code, standardId, childrenList, 0);
//            //取出每个分类科目的子科目
//            List<DmBudgetSubject> children = e.getChildren();
//            if (children !=null && children.size() !=0){
//                children.stream().forEach(child ->{
//                    child.setStandardId(standard.getId());
//                    childrenList.add(child);
//                });
//            }
        });


        subjectList.addAll(childrenList);
        boolean addSubjectS = subjectService.saveBatch(subjectList);
        return addSubjectS;
    }


    // 递归方法，取出每个分类科目的子科目
    private void addChildren(DmBudgetSubject parent, String parentCode, String standardId, List<DmBudgetSubject> childrenList, int level) {
        parent.setSubjectLevel(level); // 设置当前层级
        List<DmBudgetSubject> children = parent.getChildren();
        if (children != null && !children.isEmpty()) {
//            parent.setHasChildren(1); // 设置 hasChildren 为 1
            children.forEach(child -> {
                child.setStandardId(standardId);
                child.setUpCode(parentCode);
                String code = child.getCode();
                childrenList.add(child);
                // 递归调用处理子科目的子科目
                addChildren(child, code, standardId, childrenList, level + 1);
            });
        }
        // 确保最终的 hasChildren 状态正确
        parent.setHasChildren((children != null && !children.isEmpty()) ? 1 : 0);
    }

    /**
     * 删除预算标准信息
     *
     * @param id 预算标准主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteDmBudgetStandardByID(String id) {
        LambdaQueryWrapper<DmBudgetSubject> lqwSubject = new LambdaQueryWrapper<>();
        lqwSubject.eq(DmBudgetSubject::getStandardId, id);
        long count = subjectService.count(lqwSubject);
        //从表数量为0
        if (count == 0) {
            return baseMapper.deleteById(id) > 0;
        }
        //从表数量不为0
        LambdaUpdateWrapper<DmBudgetSubject> luwSubject = new LambdaUpdateWrapper<>();
        luwSubject.eq(DmBudgetSubject::getStandardId, id);
        boolean remove = subjectService.remove(luwSubject);
        //先查
        DmBudgetStandard dmBudgetStandard = baseMapper.selectById(id);
        //后删
        Boolean delBase = baseMapper.deleteById(id) > 0;

        //删除所携带的附件
        String policyFileId = dmBudgetStandard.getPolicyFileId();
        if (StringUtils.isNotEmpty(policyFileId)) {
            List<String> list = Arrays.asList(policyFileId.split(","));
            for (String s : list) {
                fileApi.delFile(s);
            }
        }

        return delBase && remove;
    }


    @Override
    public String getMaxPrefix(String projectClass) {
        String maxPrefix = baseMapper.getMaxPrefix(projectClass);
        if (maxPrefix == null) {
            return "";
        } else {
            return maxPrefix;
        }
    }


    @Override
    public String getYsbzIdByxmflId(String projectClassId, Date projectDate) {
        //根据项目分类code获取一下分类id
        List<DmProjectType> projectTypeList = projectTypeService.selectDmProjectTypeList(projectClassId, null, null, null);
        if (projectTypeList != null && projectTypeList.size() > 0) {
            projectClassId = projectTypeList.get(0).getId();
        }

        if (StringUtils.isEmpty(projectClassId) || projectDate == null) return "";
        LambdaQueryWrapper<DmBudgetStandardDate> lqw = new LambdaQueryWrapper();
        lqw.eq(DmBudgetStandardDate::getProjectTypeId, projectClassId);
        lqw.le(DmBudgetStandardDate::getStartDate, projectDate)  //立项时间大于起始时间->起始时间小于立项时间
                .ge(DmBudgetStandardDate::getEndDate, projectDate);  // 立项时间小于结束时间 ->结束时间大于立项时间
        DmBudgetStandardDate dmBudgetStandardDate = standardDateMapper.selectOne(lqw);
        if (dmBudgetStandardDate == null) {
            return "";
        } else {
            return dmBudgetStandardDate.getBudgetStandardId();
        }
    }

    @Override
    public List<DmBudgetSubject> getYskmListByxmflId(String projectClassId, Date projectDate) {
        //预算标准id
        String ysbzId = this.getYsbzIdByxmflId(projectClassId, projectDate);
        if (StringUtils.isEmpty(ysbzId)) return null;
        //2.根据预算标准id查询预算科目集合
        LambdaQueryWrapper<DmBudgetSubject> subjectQuery = new LambdaQueryWrapper<>();
        subjectQuery.eq(DmBudgetSubject::getStandardId, ysbzId);
        List<DmBudgetSubject> subjectList = subjectService.list(subjectQuery);
        List<DmBudgetSubject> subjectTree = buildTree("", subjectList);
        return subjectTree;
    }

}
